home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / satellit / pbsv004 / pbsv.c < prev    next >
C/C++ Source or Header  |  1993-08-05  |  13KB  |  653 lines

  1. /* pbsv.c 1993.8.6 */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <assert.h>
  7. /* #include <io.h> */
  8. #include <time.h>
  9. #include <sys/stat.h>
  10.  
  11. #include "pbsv.h"
  12.  
  13. extern int svcfg();            /* pbcfg.c */
  14. extern VOID dspinfo();
  15. extern int initdir();            /* pbdir.c */
  16. extern VOID qst_dir();
  17. extern int req_dir();
  18. extern int pfhstat(char*,struct stpfh*);
  19. extern VOID cmd();            /* pbcmd.c */
  20. extern VOID initq(),putq();        /* pblib.c */
  21. extern VOID delq();
  22. extern struct stqcell *getq();
  23. extern VOID ca2ad(),ad2ca();
  24. extern int ckcrc();
  25. extern int calc_crc();            /* crc.c */
  26.  
  27. extern VOID inikss(),exitkss();        /* pbkiss.c */
  28. extern VOID rcvkss(),sndkss();
  29.  
  30.  
  31. extern BOOL f_rkss,f_skss;
  32. extern int lnrkss,lnskss;
  33. extern char rkss[],skss[];
  34.  
  35. struct stuser user[MAXUSER];
  36. struct sthole hole[MAXHOLE];
  37.  
  38. struct stqueue actuser;
  39. struct stqueue freeuser;
  40. struct stqueue freehole;
  41.  
  42. /* pbdv config data */
  43.  
  44. char cfgfile[128] = {"pbsv.cfg"};
  45.  
  46. char bdcall[CALLSIZE];
  47. char bdadrs[ADRSIZE];
  48. int port = 0;            /* COM1 */
  49.  
  50. /* kiss mode parm */
  51.  
  52. int txd      = 300;
  53. int persist  = NOT_DEFINE;
  54. int slottime = NOT_DEFINE;
  55. int txtail   = NOT_DEFINE;
  56. int fullduplex = NOT_DEFINE;
  57. int sethardware = NOT_DEFINE;
  58. int softdcd = NOT_DEFINE;
  59.  
  60. int  kissrom = 0;
  61. int  multikiss = 0;
  62. char dldir[128];
  63.  
  64. char hdrqst[HDRSIZE];        /* QST-1 header pid = bb            */
  65. char hdrdqst[HDRSIZE];        /* QST-1 directory header pid = pd    */
  66. char hdrpblst[HDRSIZE];     /* PBLIST header    */
  67. char hdrokno[HDRSIZE];      /* OK / NO */
  68. char hdreq[HDRSIZE];        /* request pid = bb */
  69.  
  70. /* flags */
  71. BOOL f_debug = OFF;
  72. BOOL f_exit    = OFF;
  73. BOOL f_beacon  = OFF;
  74. BOOL f_verbose = OFF;
  75. BOOL f_headers = OFF;
  76. BOOL f_hex     = OFF;
  77.  
  78. clock_t tim_0;            /* timer PBLIST */
  79. clock_t tim_1,tim_2;
  80. clock_t tim_3;            /* exit timer */
  81.  
  82. BOOL f_etim = OFF;
  83. long exit_timer = 60*30;
  84.  
  85. /*
  86.  * < main > main
  87.  */
  88. VOID main(argc,argv)
  89. int argc;
  90. char *argv[];
  91. {
  92.     VOID initsv(),pbsv();
  93.  
  94.     int i,n;
  95.  
  96.     printf("*** Broadcast Server ***\n");
  97.     printf("PBSV ver%s%s",PBSV_VER,PBSV_ID);
  98.     printf(" by N.Okamoto JN2LHU @ JN2BDS.19.JNET2.JPN.AS\n");
  99.  
  100.     for (i = 1; i < argc; i++) {
  101.         if (argv[i][0] == '-') {
  102.         switch(argv[i][1]) {
  103.             case 'v': case 'V':
  104.             f_verbose = ON;
  105.             break;
  106.         case 'q': case 'Q':
  107.             f_exit = ON;
  108.             break;
  109.         case 's': case 'S':
  110.             exit_timer = (clock_t)atol(&argv[i][2]);
  111.             f_etim = ON;
  112.             break;
  113.         default:
  114.             if (strcmp(&argv[i][1],"debug") == 0) {
  115.                 f_debug = ON;
  116.             }
  117.             break;
  118.         }
  119.     } else {
  120.         strcpy(cfgfile,argv[i]);
  121.     }
  122.     }
  123.  
  124.     svcfg();
  125.     initsv();
  126.  
  127.     n = initdir();
  128.     if (n == 0) {
  129.         printf("Error: DL files not exist\n");
  130.     exit(1);
  131.     }
  132.  
  133.     pbsv();
  134. }
  135.  
  136. /*
  137.  * < initsv > init pbsv
  138.  */
  139. VOID initsv()
  140. {
  141.     char *p;
  142.     int i;
  143.  
  144.     initq(&actuser);
  145.     initq(&freeuser);
  146.     for (i = 0; i < MAXUSER; i++) {
  147.         putq(&freeuser,&user[i]);
  148.     }
  149.     initq(&freehole);
  150.     for (i = 0; i < MAXHOLE; i++) {
  151.         putq(&freehole,&hole[i]);
  152.     }
  153.  
  154.     hdrqst[0] = (multikiss<<4);
  155.     ca2ad("QST-1",hdrqst+1);
  156.     memcpy(hdrqst+1+ADRSIZE,bdadrs,ADRSIZE);
  157.     hdrqst[7]  &= 0x1f;        /* C,RR not used */
  158.     hdrqst[14] &= 0x1f;
  159.     hdrqst[14] |= 0x01;
  160.     hdrqst[15] = 0x03;        /* UI */
  161.     hdrqst[16] = 0xbb;        /* PID = BB */
  162.     memcpy(hdrokno,hdrqst,HDRSIZE);
  163.     hdrokno[16] = 0xf0;
  164.     memcpy(hdrdqst,hdrqst,HDRSIZE);
  165.     hdrdqst[16] = 0xbd;        /* PID = BD */
  166.     memcpy(hdrpblst,hdrqst,HDRSIZE);
  167.     ca2ad("PBLIST",hdrpblst+1);
  168.     hdrpblst[16] = 0xf0;    /* PID = F0 */
  169.  
  170.     p = hdreq;
  171.     p[0] = 0x00;
  172.     memcpy(p+1,bdadrs,7);
  173.     p[7]  &= 0x1f;        /* C,RR not used */
  174.     p[14] &= 0x1f;
  175.     p[14] |= 0x01;
  176.     p[15] = 0x03;        /* UI */
  177.     p[16] = 0xbb;        /* PID = BB */
  178. }
  179.  
  180. /*
  181.  * < pbsv > PB-server
  182.  */
  183. VOID pbsv()
  184. {
  185.     VOID timer(),qst(),pblist(int);
  186.     VOID rcvreq();
  187.  
  188.     timer();
  189.     tim_3 = exit_timer;
  190.  
  191.     inikss();
  192.     for (;;) {
  193.         cmd();
  194.     timer();
  195.         pblist(0);
  196.         qst();
  197.     rcvreq();
  198.     rcvkss();
  199.     if (f_etim && tim_3 == 0) {
  200.         f_exit = ON;
  201.         if (f_verbose)
  202.             printf("exit timer count up\n");
  203.     }
  204.         if (f_exit) {
  205.         break;
  206.     }
  207.     }
  208.     exitkss();
  209. }
  210.  
  211. /*
  212.  * < timer > timer
  213.  */
  214. VOID timer()
  215. {
  216.     static clock_t t1;
  217.     clock_t clk,t;
  218.  
  219.     clk = clock();
  220.     t = clk - t1;
  221.     t1 = clk;
  222.  
  223.     if ((u_long)tim_0 > (u_long)t) {
  224.         tim_0 -= t;
  225.     } else
  226.         tim_0 = 0;
  227.  
  228.     if ((u_long)tim_1 > (u_long)t) {
  229.         tim_1 -= t;
  230.     } else
  231.         tim_1 = 0;
  232.  
  233.     if ((u_long)tim_2 > (u_long)t) {
  234.         tim_2 -= t;
  235.     } else
  236.         tim_2 = 0;
  237.  
  238.     if ((u_long)tim_3 > (u_long)t) {
  239.         tim_3 -= t;
  240.     } else
  241.         tim_3 = 0;
  242. }
  243.  
  244. /*
  245.  * < pblist > PB list
  246.  */
  247. VOID pblist(ctl)
  248. int ctl;
  249. {
  250.     VOID add_kss(char*,int);
  251.  
  252.     char buf[256];
  253.     int n;
  254.     struct stuser *user;
  255.  
  256.     if (f_beacon) {
  257.         f_beacon = OFF;
  258.         tim_0 = 0;
  259.     }
  260.     if (ctl == 1)
  261.         tim_0 = 0;
  262.     else {
  263.         if (tim_0 != 0 || actuser.head != NULL)
  264.         return;
  265.     }
  266.  
  267.     if (tim_0 != 0)
  268.         return;
  269.     tim_0 = 30;
  270.     strcpy(buf,"PB:");
  271.     user = (struct stuser *)actuser.head;
  272.     n = 0;
  273.     if (user == NULL) {
  274.         strcat(buf," Empty.");
  275.     } else {
  276.         while(user != NULL) {
  277.         strcat(buf," ");
  278.         strcat(buf,user->call);
  279.         if (user->flags & F_DIR)
  280.             strcat(buf,"\\D");
  281.         user = user->next;
  282.         n++;
  283.     }
  284.     }
  285.     printf("PBLIST: %s\n",buf);
  286.     lnskss = 0;
  287.     add_kss(hdrpblst,HDRSIZE);
  288.     add_kss(buf,strlen(buf));
  289.     sndkss();
  290. }
  291.  
  292. /*
  293.  * < qst >
  294.  */
  295. VOID qst()
  296. {
  297.     VOID qst_bul();
  298.     VOID del_user(struct stuser*);
  299.  
  300.     struct stuser *user;
  301.  
  302.  
  303.     if (actuser.head == NULL)
  304.         return;
  305.  
  306.     pblist(1);
  307.     user = (struct stuser *)getq(&actuser);
  308.                     /* check time over ? */
  309.     if ((u_long)(clock() - user->entry_t) > (u_long)180) {
  310.     if (f_verbose) {
  311.         printf("Delete %s in PBLIST\n",user->call);
  312.     }
  313.         del_user(user);
  314.         return;
  315.     }
  316.  
  317.     if (user->flags & F_DIR) {
  318.         qst_dir(user);
  319.     } else {
  320.         qst_bul(user);
  321.     }
  322.  
  323.     if (user->hole.head == NULL) {
  324.         putq(&freeuser,user);
  325.     } else {
  326.         putq(&actuser,user);
  327.     }
  328.     if (actuser.head == NULL) {
  329.         f_beacon = ON;
  330.     }
  331.  
  332. }
  333.  
  334. /*
  335.  * < qst_bul >
  336.  */
  337. VOID qst_bul(user)
  338. struct stuser *user;
  339. {
  340.     char *dlname(long);
  341.     VOID add_kss(char*,int),add_crc();
  342.  
  343.     struct sthole *hole;
  344.     char name[128];
  345.     char buf[256];
  346.     FILE *fp;
  347.     char flags,file_type;
  348.     long file_id,offset;
  349.     int i;
  350.     u_int size;
  351.  
  352.  
  353.     file_id   = user->file_id;
  354.     file_type = user->file_type;
  355.     strcpy(name,dlname(file_id));
  356.     if ((fp = fopen(name,"rb")) == NULL) {
  357.         printf("QST-1 file[%s] open error\n",name);
  358.         exit(1);
  359.     }
  360.     flags = 0x02;
  361.     for (i = 0; i < 5; i++) {
  362.         hole = (struct sthole *)user->hole.head;
  363.     if (hole == NULL)
  364.         break;
  365.         offset = hole->offset;
  366.         if (user->block_size > hole->length) {
  367.             size = hole->length;
  368.         } else {
  369.             size = user->block_size;
  370.         }
  371.         hole->offset += (long)size;
  372.     hole->length -= size;
  373.     if (hole->length == 0) {
  374.         hole = (struct sthole *)getq(&user->hole);
  375.         putq(&freehole,hole);
  376.     }
  377.     printf("QST-1: %lx msg offset=%ld,len=%d\n",file_id,offset,size);
  378.         fseek(fp,offset,SEEK_SET);
  379.         fread(buf,size,1,fp);
  380.     lnskss = 0;
  381.         add_kss(hdrqst,HDRSIZE);
  382.     add_kss(&flags,1);
  383.     add_kss((char*)&file_id,4);
  384.     add_kss(&file_type,1);
  385.         add_kss((char*)&offset,3);
  386.         add_kss(buf,size);
  387.     add_crc();
  388.         sndkss();
  389.     }
  390.     fclose(fp);
  391. }
  392.  
  393. VOID add_kss(p,n)
  394. char *p;
  395. int n;
  396. {
  397.     while(n-- > 0) {
  398.         skss[lnskss++] = *p++;
  399.     }
  400. }
  401.  
  402. VOID add_crc()
  403. {
  404.     int j,crc;
  405.  
  406.     for (j = HDRSIZE, crc = 0; j < lnskss; j++)
  407.         crc = calc_crc(skss[j],crc);
  408.     skss[lnskss++] = (crc >> 8) & 0xff;
  409.     skss[lnskss++] = crc & 0xff;
  410.     ckcrc(skss,lnskss);
  411. }
  412.  
  413. /*
  414.  * < rcvreq > recive request
  415.  */
  416. VOID rcvreq()
  417. {
  418.     int  req_bul();
  419.     VOID res_msg(char*,int);
  420.     struct stuser *sch_user(char*);
  421.     VOID del_user(struct stuser*);
  422.  
  423.     char callsign[10];
  424.     int r,i;
  425.     u_char pid;
  426.  
  427.     if (!f_rkss)
  428.         return;
  429.  
  430.     f_rkss = OFF;
  431.  
  432.     if (lnrkss <= HDRSIZE)
  433.         return;
  434.     for (i = 0; i < HDRSIZE-1; i++) {
  435.         if (i >= (1+ADRSIZE) && i < (1+ADRSIZE+ADRSIZE)) {/* skip src adrs */
  436.         ;
  437.         } else if ((rkss[i] & 0xff) != (hdreq[i] & 0xff)) {
  438.         return;
  439.     }
  440.     }
  441.     pid = rkss[i];
  442.     ad2ca(rkss+1+ADRSIZE,callsign);
  443.     del_user(sch_user(callsign));
  444.     switch(pid) {
  445.         case 0xbb:        /* pid = bb */
  446.         r = req_bul(callsign);
  447.         break;
  448.     case 0xbd:        /* pid = bd */
  449.         r = req_dir(callsign);
  450.         break;
  451.     default:
  452.         printf("Error: rcv frame error\n");
  453.         return;
  454.     }
  455.     res_msg(callsign,r);
  456. }
  457.  
  458. /*
  459.  * < res_msg > response messages
  460.  */
  461. VOID res_msg(callsign,errorcode)
  462. char *callsign;
  463. int errorcode;
  464. {
  465.     char buf[64];
  466.  
  467.     if (errorcode == 0) {
  468.         sprintf(buf,"OK %s\r",callsign);
  469.     } else {
  470.         sprintf(buf,"NO %d %s\r",errorcode,callsign);
  471.     }
  472.     lnskss = 0;
  473.     add_kss(hdrokno,HDRSIZE);
  474.     ca2ad(callsign,skss+1);
  475.     add_kss(buf,strlen(buf));
  476.     sndkss();
  477. }
  478.  
  479. /*
  480.  * < req_bul > request
  481.  */
  482. int req_bul(callsign)
  483. char *callsign;
  484. {
  485.     int set_user(struct stuser*,char*,long,u_int);
  486.     int add_hole(struct stuser*,long,u_int);
  487.     char *dlname(long);
  488.  
  489.     u_char flags;
  490.     long file_id,offset;
  491.     u_int block_size,length;
  492.     int i;
  493.     struct stuser *user;
  494.  
  495.     i = HDRSIZE;
  496.     flags = rkss[i];
  497.     i += 1;
  498.     memcpy(&file_id,&rkss[i],4);
  499.     i += 4;
  500.     memcpy(&block_size,&rkss[i],2);
  501.     i += 2;
  502.     if (access(dlname(file_id),00) != 0) {    /* DL file exist ? */
  503.         return(-2);    /* file does not exist */
  504.     }
  505.     user = (struct stuser *)getq(&freeuser);
  506.     if (user == NULL) {
  507.     return(-1);    /* queue full */
  508.     }
  509.     switch(flags & 0x03) {
  510.         case 0x00:            /* start */
  511.         printf("%s: Start, msg %lx, %d byte frames.\n",
  512.             callsign,file_id,block_size);
  513.         set_user(user,callsign,file_id,block_size);
  514.         offset = 0;
  515.         length = block_size * 10;
  516.         for (i = 0; i < 10; i++) {
  517.             add_hole(user,offset,length);
  518.         offset += length;
  519.         }
  520.         break;
  521.  
  522.         case 0x01:            /* stop */
  523.         printf("%s: Stop, msg %lx.\n",callsign,file_id);
  524.         break;
  525.  
  526.     case 0x02:            /* hole list */
  527.         printf("%s: Fill, msg %lx, %d byte frames.\n",
  528.             callsign,file_id,block_size);
  529.         set_user(user,callsign,file_id,block_size);
  530.         for ( ; i < lnrkss; i += (3+2)) {
  531.             offset = 0;
  532.             memcpy(&offset,&rkss[i],3);
  533.             memcpy(&length,&rkss[i+3],2);
  534.                 add_hole(user,offset,length);
  535.         printf("        offset: %06lx length:%04x\n",offset,length);
  536.         }
  537.         break;
  538.  
  539.     default:
  540.         return(-4);        /* debug */
  541.         break;
  542.     }
  543.     return(0);        /* OK */
  544. }
  545.  
  546. /*
  547.  * < set_user > set user list
  548.  */
  549. int set_user(user,callsign,file_id,block_size)
  550. struct stuser *user;
  551. char *callsign;
  552. long file_id;
  553. u_int block_size;
  554. {
  555.     char *dlname(long);
  556.  
  557.     struct stat sbuf;
  558.     struct stpfh pfh;
  559.     char pathname[128];
  560.  
  561.     strcpy(pathname,dlname(file_id));
  562.     stat(pathname,&sbuf);
  563.     pfhstat(pathname,&pfh);
  564.     user->entry_t = clock();
  565.     user->flags = 0x0000;
  566.     strcpy(user->call,callsign);
  567.     user->file_id    = file_id;
  568.     user->file_type  = pfh.file_type;
  569.     user->file_size  = sbuf.st_size;
  570.     if (block_size > MAXBLKSIZE) {    /* block size adjust */
  571.         user->block_size = MAXBLKSIZE;
  572.     } else {
  573.         user->block_size = block_size;
  574.     }
  575.     initq(&user->hole);
  576.     putq(&actuser,user);
  577. }
  578.  
  579. /*
  580.  * < add_hole >
  581.  */
  582. int add_hole(user,offset,length)
  583. struct stuser *user;
  584. long offset;
  585. u_int length;
  586. {
  587.     struct sthole *hole;
  588.  
  589.     if (offset >= user->file_size)
  590.         return;
  591.  
  592.     if (offset + length > user->file_size)    /* adjust */
  593.         length = user->file_size - offset;
  594.  
  595.     hole = (struct sthole *)getq(&freehole);
  596.     if (hole == NULL) {
  597.         assert(0);
  598.     }
  599.     hole->offset = offset;
  600.     hole->length = length;
  601.     putq(&user->hole,hole);
  602. }
  603.  
  604. /*
  605.  * < sch_user > search user
  606.  */
  607. struct stuser *sch_user(callsign)
  608. char *callsign;
  609. {
  610.     struct stuser *user;
  611.  
  612.     user = (struct stuser *)actuser.head;
  613.     while(user) {
  614.     if (strcmp(user->call,callsign) == 0) {
  615.         break;
  616.     }
  617.     user = (struct stuser *)user->next;
  618.     }
  619.     return(user);
  620. }
  621.  
  622. /*
  623.  * < del_user > delete user
  624.  */
  625. VOID del_user(user)
  626. struct stuser *user;
  627. {
  628.     struct sthole *hole;
  629.  
  630.     if (user == NULL)
  631.         return;
  632.  
  633.     while(hole = (struct sthole *)getq(&user->hole)) {
  634.         putq(&freehole,hole);
  635.     }
  636.     delq(&actuser,user);
  637.     putq(&freeuser,user);
  638. }
  639.  
  640. /*
  641.  * < dlname > pathname DL file
  642.  */
  643. char *dlname(file_id)
  644. long file_id;
  645. {
  646.     static char pathname[128];
  647.  
  648.     sprintf(pathname,"%s%lx.DL",dldir,file_id);
  649.     return(pathname);
  650. }
  651.  
  652. /* pbsv.c */
  653.